#include "device/dev_static.h"


namespace iecas_ns
{
    shared_ptr<CDevStatic> CDevStatic::sm_intancePtr = nullptr;

    CDevStatic::CDevStatic()
    {
        m_commonPtr = shared_ptr<CCommon>(CCommon::getInstance());
        m_jsonUsrPtr = shared_ptr<CJsonUsr>(CJsonUsr::getInstance());
        m_devCommonPtr = shared_ptr<CDevCommon>(CDevCommon::getInstance());
        m_port_fd.clear();
        m_uninitDev.clear();
        pwd_shell = "sh $PWD/";
    }

	shared_ptr<CDevStatic> CDevStatic::getInstance()
	{
		if(sm_intancePtr == nullptr)
		{
			sm_intancePtr = shared_ptr<CDevStatic>(new CDevStatic());
		}
		return sm_intancePtr;
	}

    bool CDevStatic::init(void)
    {
        get_original_dev();
        staticJudge();

        return true;
    }

    void CDevStatic::start(void)
    {
        thread tempThread(&CDevStatic::loop, this);
        tempThread.detach();
    }

    void CDevStatic::loop(void)
    {
        get_connected_usb_dev();
        staticJudge();
        cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!get_connected_usb_dev() PASS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
        PLOGD << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!get_connected_usb_dev() PASS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";

        while(true)
        {

        }
    }

    bool CDevStatic::get_original_dev(void)
    {
        Value dev;
        m_jsonUsrPtr->getAllParams(dev);

        int i;
        if(dev.isMember(ORIGINAL_DEV))
        {
            for(i = 0; i < dev[ORIGINAL_DEV].size(); i++)
            {
                cout << "get .json " << ORIGINAL_DEV << ": " << dev[ORIGINAL_DEV][i][SRC_DEV].asString() << endl;
                PLOGD << "get .json " << ORIGINAL_DEV << ": " << dev[ORIGINAL_DEV][i][SRC_DEV].asString();
                m_uninitDev.push_back(dev[ORIGINAL_DEV][i][SRC_DEV].asString());
            }
        }
        else
        {
            cout << "get .json " << ORIGINAL_DEV << " invalid" << endl;
            PLOGD << "get .json " << ORIGINAL_DEV << " invalid";
            return false;
        }

        return true;
    }

    void CDevStatic::get_connected_usb_dev(void)
    {
        string cmd_shell;

        cmd_shell = pwd_shell + GET_USB_DEV_SH_FILE_NAME + " " + IGNORE_USB_DEV_TXT_FILE_NAME + " " + CONNECTED_USB_DEV_TXT_FILE_NAME;

        cout << "cpp call linux shell: " << cmd_shell << endl;
        PLOGD << "cpp call linux shell: " << cmd_shell;

        system(cmd_shell.c_str());
        sleep(3);

        cout << "cpp call linux shell: " << cmd_shell << " success" << endl;
        PLOGD << "cpp call linux shell: " << cmd_shell << " success";

        ifstream ifs;
        ifs.open(CONNECTED_USB_DEV_TXT_FILE_NAME, ios::in);
        if (!ifs.is_open()) 
        {
            cout << "open " << CONNECTED_USB_DEV_TXT_FILE_NAME << " failed" << endl;
            PLOGD << "open " << CONNECTED_USB_DEV_TXT_FILE_NAME << " failed";
            return;
        }
        else
        {
            cout << "open " << CONNECTED_USB_DEV_TXT_FILE_NAME << " success" << endl;
            PLOGD << "open " << CONNECTED_USB_DEV_TXT_FILE_NAME << " success";
        }

        string tmp;
        while(getline(ifs, tmp))
        {
            cout << "get .txt usb dev: " << tmp << endl;
            PLOGD << "get .txt usb dev: " << tmp;
            m_uninitDev.push_back(tmp);
        }
        ifs.close();
    }

    void CDevStatic::staticJudge(void)
    {
        int i;

        string dev_s, sub_s;
        string::size_type idx;
        for(i = 0; i < m_uninitDev.size(); i++)
        {
            dev_s = m_uninitDev.at(i);
            sleep(1);

            sub_s = "/dev/tty";
            idx = dev_s.find(sub_s);
            if(idx != string::npos)
            {
                cout << "++++++++++ Add serial " << dev_s << " ++++++++++" << endl;
                PLOGD << "++++++++++ Add serial " << dev_s << " ++++++++++";
                m_devCommonPtr->init_serial(dev_s);
                continue;
            }

            sub_s = "/dev/sd";
            idx = dev_s.find(sub_s);
            if(idx != string::npos)
            {
                cout << "++++++++++ Add disk " << dev_s << " ++++++++++" << endl;
                PLOGD << "++++++++++ Add disk " << dev_s << " ++++++++++";
                m_devCommonPtr->init_usb_disk(dev_s);
                continue;
            }

            sub_s = "/dev/input/event";
            idx = dev_s.find(sub_s);
            if(idx != string::npos)
            {
                cout << "++++++++++ Add keyboard " << dev_s << " ++++++++++" << endl;
                PLOGD << "++++++++++ Add keyboard " << dev_s << " ++++++++++";
                m_devCommonPtr->init_usb_keyboard(dev_s);
                continue;
            }

            sub_s = "/dev/video";
            idx = dev_s.find(sub_s);
            if(idx != string::npos)
            {
                cout << "++++++++++ Add camera " << dev_s << " ++++++++++" << endl;
                PLOGD << "++++++++++ Add camera " << dev_s << " ++++++++++";
                m_devCommonPtr->init_usb_camera(dev_s);
                continue;
            }

            sub_s = "usb";
            idx = dev_s.find(sub_s);
            if(idx != string::npos)
            {
                cout << "++++++++++ Add net " << dev_s << " ++++++++++" << endl;
                PLOGD << "++++++++++ Add net " << dev_s << " ++++++++++";
                m_devCommonPtr->init_usb_net(dev_s);
                continue;
            }

            sub_s = "/dev/mmcblk2";
            idx = dev_s.find(sub_s);
            if(idx != string::npos)
            {
                cout << "++++++++++ Add sdcard " << dev_s << " ++++++++++" << endl;
                PLOGD << "++++++++++ Add sdcard " << dev_s << " ++++++++++";
                m_devCommonPtr->init_sdcard(dev_s);
                continue;
            }
        }
        m_uninitDev.clear();
    }
}
